﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using ShredTheLog.Api;
using System.Windows.Input;
using ShredTheLog.Common.MVVM;
using ShredTheLog.Views;
using ShredTheLog.ViewModels;
using System.Diagnostics.Contracts;
using System.Windows.Media;
using ShredTheLog.Controls;
using System.Windows;

namespace ShredTheLog.Plugins
{
    [Export(typeof(ICommandListItem))]
    [MenuCommandMetadata(Menu = Menus.Tools, Order = 0, Group = null)]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public sealed class ShowOptionsCommand : DelegateCommand, IUiCommand
    {
        [Import]
        private IShredServices ShredServices { get; set; }

        public ShowOptionsCommand()
            : base(
            () =>
            {
                var window = Application.Current.Windows.OfType<SettingsView>().SingleOrDefault();
                if (window == null)
                    new SettingsView().Show(new SettingsViewModel());
                else
                    window.Activate();
            })
        {
        }

        public string Name { get { return ShredServices.GetLocalizedString("s_Options"); } }
        public ImageSource Image { get { return null; } }
    }

    [Export(typeof(ICommandListItem))]
    [MenuCommandMetadata(Menu = Menus.Tools, Order = 100, Group = null)]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public sealed class ThemesCommandGroup : ICommandGroup
    {
        [Import]
        private IShredServices ShredServices { get; set; }

        [Import]
        private IUiSettingsSection UiSettings { get; set; }

        [ImportMany]
        private Lazy<ITheme, IOrderMetadata>[] _themes = null;
        private IEnumerable<ITheme> Themes
        {
            get 
            {
                Contract.Ensures(Contract.Result<IEnumerable<ITheme>>() != null);
                Contract.Assume(_themes != null);

                return from i in _themes orderby i.Metadata.Order select i.Value; 
            }
        }

        public string Name { get { return ShredServices.GetLocalizedString("s_Menu_Theme"); } }
        public ImageSource Image { get { return null; } }

        public IEnumerable<ICommandListItem> Items
        {
            get { return Themes.Select(i => new SetThemeCommand(i, ShredServices, UiSettings)); }
        }
    }

    public sealed class SetThemeCommand : DelegateCommand, IUiCommand
    {
        public SetThemeCommand(ITheme theme, IShredServices shredServices, IUiSettingsSection uiSettings)
            : base(
            () => 
            {
                try
                {
                    ViewFactory.RecreateViews(
                        () =>
                        {
                            uiSettings.ThemeID = theme.ID;
                            shredServices.SaveSettings();
                        });
                }
                catch (Exception ex)
                {
                    shredServices.ShowError(() => shredServices.GetLocalizedString("s_FailedToApplySettings"), ex);
                }
            })
        {
            Contract.Requires(theme != null);
            Contract.Requires(shredServices != null);
            Contract.Requires(uiSettings != null);

            Name = theme.Name;
        }

        public string Name { get; private set; }
        public ImageSource Image { get { return null; } }
    }

    [Export(typeof(ICommandListItem))]
    [MenuCommandMetadata(Menu = Menus.Tools, Order = 200, Group = null)]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public sealed class UiLanguagesCommandGroup : ICommandGroup
    {
        [Import]
        private IShredServices ShredServices { get; set; }

        [Import]
        private IUiSettingsSection UiSettings { get; set; }

        [ImportMany]
        private Lazy<IUiLanguage, IOrderMetadata>[] _uiLanguages = null;
        private IEnumerable<IUiLanguage> UiLanguages
        {
            get 
            {
                Contract.Ensures(Contract.Result<IEnumerable<IUiLanguage>>() != null);
                Contract.Assume(_uiLanguages != null);

                return from i in _uiLanguages orderby i.Metadata.Order select i.Value; 
            }
        }

        public string Name { get { return ShredServices.GetLocalizedString("s_Menu_Language"); } }
        public ImageSource Image { get { return null; } }

        public IEnumerable<ICommandListItem> Items
        {
            get { return UiLanguages.Select(i => new SetUiLanguageCommand(i, ShredServices, UiSettings)); }
        }
    }

    public sealed class SetUiLanguageCommand : DelegateCommand, IUiCommand
    {
        public SetUiLanguageCommand(IUiLanguage uiLanguage, IShredServices shredServices, IUiSettingsSection uiSettings)
            : base(
            () =>
            {
                try
                {
                    ViewFactory.RecreateViews(
                        () =>
                        {
                            uiSettings.UiLanguage = uiLanguage.Language;
                            shredServices.SaveSettings();
                        });
                }
                catch (Exception ex)
                {
                    shredServices.ShowError(() => shredServices.GetLocalizedString("s_FailedToApplySettings"), ex);
                }
            })
        {
            Contract.Requires(uiLanguage != null);
            Contract.Requires(shredServices != null);
            Contract.Requires(uiSettings != null);

            Name = uiLanguage.Name;
        }

        public string Name { get; private set; }
        public ImageSource Image { get { return null; } }
    }
}
